Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

espanso: add sandboxing for systemd service #5957

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

talal
Copy link
Contributor

@talal talal commented Oct 12, 2024

Description

  • Add sandboxing for systemd service

Checklist

  • Change is backwards compatible.

  • Code formatted with ./format.

  • Code tested through nix-shell --pure tests -A run.all or nix develop --ignore-environment .#all using Flakes.

  • Test cases updated/added. See example.

  • Commit messages are formatted like

    {component}: {description}
    
    {long description}
    

    See CONTRIBUTING for more information and recent commit messages for examples.

  • If this PR adds a new module

    • Added myself as module maintainer. See example.

Maintainer CC

@n8henrie @lucasew @liyangau

@talal talal force-pushed the espanso-sandboxing branch from f1dc88d to ff2f6b3 Compare October 12, 2024 07:34
@n8henrie
Copy link
Contributor

Have you tested on Wayland by chance? Might be tricky since it's not working as is on nixos.

@pitkling and I have an ongoing discussion on the best way to manage the capabilities that are required for the evdev backend, in the context of espanso's forking and good faith effort to drop capabilities as early as possible. We have a couple open PRs, and I'm particularly interested in compatibility of these systemd changes with his PR, which I think is what we'll eventually go with for Wayland compatibility.

@talal
Copy link
Contributor Author

talal commented Oct 12, 2024

This systemd service config is what I have been using on GNOME with Wayland for the last couple of months.

I wanted to upstream this config so that others may benefit too.

However, for posterity, it should be noted that I use

services.espanso.package = pkgs.espanso-wayland;

@n8henrie
Copy link
Contributor

Interesting. I haven't been able to get espanso to work on Wayland without setcap (on non-nixos) or running as root. Is your config available somewhere?

@talal
Copy link
Contributor Author

talal commented Oct 13, 2024

Ahh, you're right. I'm sorry, I forgot about the setcap since I did that step before I switched to home-manager.

I ran the command as mentioned in https://espanso.org/docs/install/linux#adding-the-required-capabilities

But, please feel free to correct me if I'm wrong, I don't think this is within the scope of home-manager—changes like capabilities are not a part of home-manager, right?

For example, some packages require adding a udev rule and so they end up adding a new file under /etc/udev/rules.d but this is not done by home-manager or does home-manager also make such changes? I actually have no idea about this because I manage my udev rules manually on my non-NixOS home-manager setup.

@pitkling
Copy link
Contributor

Ahh, you're right. I'm sorry, I forgot about the setcap since I did that step before I switched to home-manager.

I ran the command as mentioned in https://espanso.org/docs/install/linux#adding-the-required-capabilities

But, please feel free to correct me if I'm wrong, I don't think this is within the scope of home-manager—changes like capabilities are not a part of home-manager, right? […]

No, you're completely right, the problem @n8henrie is referring to cannot be fixed by Home Manager. But we have some PRs in NixOS (namely #328890 and #339594 ) that try to fix the Wayland issue. The sudo setcap … command you're referring to is actually not supposed to work on NixOS, since the nix store is usually read-only. I assume you circumvented that manually by remounting it read-write or something like that? In general, NixOS uses a wrapper mechanism (see security.wrappers to allow elevated binaries (root permissions via setuid, linux capabilities via setcap, …). Unfortunately this doesn't work for Espanso out of the box due to reasons outlined in #328890 .

I assume @n8henrie mostly was curious about the compatibility of your PR with those fixes. Since the Wayland issues are related to capabilities, sandboxing is likely to affect them.

I tried your PR together with my PR #328890 for the Wayland issue and indeed I ran into some problems due to the sandboxing. I did only some very quick testing so far. I expected that something like NoNewPrivileges = true; might cause problems (since upstream Espanso is relying on regaining capabilities after dropping them early on, and also security.wrappers is doing some magic with capabilities). However, it turns out I could not use any of the sandboxing options from your PR. I'm honestly not sure why, since something like SystemCallArchitectures = "native"; seems pretty unrelated and safe. But then, I don know exactly how the sandboxing options work. I'll investigate further when I have some time in the coming days.

I didn't yet test @n8henrie's PR #339594 together with your PR. It should involve changing the Home Manager service to also run /run/wrappers/bin/espanso worker similar to his PR and set up the corresponding wrapper via security.wrappers in the NixOS configuration. Would be interesting to see whether that also causes problems together with the sandboxing options.

@talal
Copy link
Contributor Author

talal commented Oct 13, 2024

I see. Since I'm using home-manager with Fedora (GNOME Wayland), I was able to use the sudo setcap ... command along with the sandboxing (as suggested in this PR) and Espanso works fine for me but I understand that this certainly needs further investigation in order for the home-manager service to work on all supported platforms—NixOS and non-NixOS.

In the meantime, I'll just continue to use systemd.user.services instead of services.espanso so that I can use the sandboxing.

@n8henrie
Copy link
Contributor

Thanks for the elaboration @pitkling, spot on. Sorry, traveling / on mobile.

@pitkling
Copy link
Contributor

@talal I looked further into this on my system, and even with the unmodified espanso-wayland package (version 2.2.1, from nixpkgs-unstable) the sandboxing options cause problems for me. More exactly, I did the following:

  • copied the binary from espanso-wayland (${pkgs.unstable.espanso-wayland}/bin/.espanso-wrapped}, which is the unmodified, unwrapped espanso binary) to ~/Desktop/espanso
  • gave that file the necessary capabilities via the sudo setcap … call from the Espanso documentation
  • adapted the user service file generated from your PR to point to the binary at ~/Desktop/espanso and reloaded it

Starting the espanso user service now fails, with the logs mentioning permissions problems. If I remove the sandboxing options from the user service file and reload the service, everything works fine.

Could you possibly post the output of systemctl --user status espanso.service (showing some infos about the service) and

journalctl _SYSTEMD_INVOCATION_ID=`systemctl --user show -p InvocationID --value espanso.service`

(showing the log output of the last invocation of the espanso user service)? Maybe I can find a hint why the sandboxing works on your system but not on mine.

@talal
Copy link
Contributor Author

talal commented Oct 16, 2024

systemctl --user status espanso.service
● espanso.service - espanso
     Loaded: loaded (/var/home/talal/.config/systemd/user/espanso.service; enabled; preset: disabled)
    Drop-In: /usr/lib/systemd/user/service.d
             └─10-timeout-abort.conf
             /run/user/1000/systemd/user.control/espanso.service.d
             └─50-CPUWeight.conf, 50-IOWeight.conf
     Active: active (running) since Mon 2024-10-14 15:07:20 CEST; 1 day 23h ago
   Main PID: 4645 (.espanso-wrappe)
      Tasks: 14 (limit: 18246)
     Memory: 12.8M (peak: 68.5M swap: 14.3M swap peak: 14.4M)
        CPU: 7min 13.760s
     CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/espanso.service
             ├─  4645 /nix/store/qqnck5hrnj7vkq2gi3vf8nk51f3yirrl-espanso-2.2-unstable-2024-05-14/bin/espanso launcher
             ├─  4653 /nix/store/qqnck5hrnj7vkq2gi3vf8nk51f3yirrl-espanso-2.2-unstable-2024-05-14/bin/.espanso-wrapped daemon
             └─189062 /nix/store/qqnck5hrnj7vkq2gi3vf8nk51f3yirrl-espanso-2.2-unstable-2024-05-14/bin/.espanso-wrapped worker --monitor-daemon --start-reason config_changed

Oct 14 18:17:09 localhost espanso[189062]: 18:17:09 [worker(189062)] [INFO] Querying modifier status...
Oct 14 18:17:09 localhost espanso[189062]: 18:17:09 [worker(189062)] [INFO] inject module will use this keyboard layout: [R=, M=, L=us, V=, O=]
Oct 14 18:17:09 localhost espanso[189062]: 18:17:09 [worker(189062)] [INFO] using EVDEVInjector
Oct 14 18:17:09 localhost espanso[189062]: 18:17:09 [worker(189062)] [INFO] using WaylandFallbackClipboard
Oct 14 18:22:46 localhost espanso[189062]: 18:22:46 [worker(189062)] [WARN] detected outdated modifier records for Meta, releasing the state
Oct 14 20:53:45 localhost espanso[189062]: 20:53:45 [worker(189062)] [WARN] detected outdated modifier records for Alt, releasing the state
Oct 16 03:32:12 localhost espanso[189062]: 03:32:12 [worker(189062)] [WARN] detected outdated modifier records for Alt, releasing the state
Oct 16 03:35:12 localhost espanso[189062]: 03:35:12 [worker(189062)] [WARN] detected outdated modifier records for Alt, releasing the state
Oct 16 05:39:57 localhost espanso[189062]: 05:39:57 [worker(189062)] [WARN] detected outdated modifier records for Meta, releasing the state
Oct 16 05:43:23 localhost espanso[189062]: 05:43:23 [worker(189062)] [WARN] detected outdated modifier records for Meta, releasing the state
journalctl _SYSTEMD_INVOCATION_ID="$(systemctl --user show -p InvocationID --value espanso.service)"
Oct 14 15:07:20 localhost espanso[4653]: 15:07:20 [daemon(4653)] [INFO] reading configs from: "/var/home/talal/.config/espanso"
Oct 14 15:07:20 localhost espanso[4653]: 15:07:20 [daemon(4653)] [INFO] reading packages from: "/var/home/talal/.config/espanso/match/packages"
Oct 14 15:07:20 localhost espanso[4653]: 15:07:20 [daemon(4653)] [INFO] using runtime dir: "/var/home/talal/.cache/espanso"
Oct 14 15:07:20 localhost espanso[4653]: 15:07:20 [daemon(4653)] [INFO] system info: Fedora Linux v40 - kernel: 6.10.12-200.fc40.x86_64
Oct 14 15:07:20 localhost espanso[4653]: 15:07:20 [daemon(4653)] [INFO] watching for changes in path: "/var/home/talal/.config/espanso"
Oct 14 15:07:20 localhost espanso[4653]: 15:07:20 [daemon(4653)] [INFO] espanso version: 2.2.1
Oct 14 15:07:20 localhost espanso[4653]: 15:07:20 [daemon(4653)] [INFO] spawning the worker process...
Oct 14 15:07:20 localhost espanso[4653]: 15:07:20 [daemon(4653)] [INFO] binded to IPC unix socket: /var/home/talal/.cache/espanso/espansodaemonv2.sock
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [INFO] reading configs from: "/var/home/talal/.config/espanso"
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [INFO] reading packages from: "/var/home/talal/.config/espanso/match/packages"
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [INFO] using runtime dir: "/var/home/talal/.cache/espanso"
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [INFO] system info: Fedora Linux v40 - kernel: 6.10.12-200.fc40.x86_64
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [INFO] using WaylandAppInfoProvider
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [INFO] binded to IPC unix socket: /var/home/talal/.cache/espanso/espansoworkerv2.sock
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [WARN] EVDEV backend is being used, but without enabling linux capabilities.
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [WARN]   Although you CAN run espanso EVDEV backend as root, it's not recommended due
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [INFO] monitoring the status of the daemon process
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [WARN]   to security reasons. Espanso supports linux capabilities to limit the attack surface
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [WARN]   area by only leveraging on the CAP_DAC_OVERRIDE capability (needed to work with
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [WARN]   /dev/input/* devices to detect and inject text) and disabling it as soon as the
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [WARN]   initial setup is completed.
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [INFO] detection module will use this keyboard layout: [R=, M=, L=us, V=, O=]
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [INFO] using EVDEVSource
Oct 14 15:07:20 localhost espanso[4661]: 15:07:20 [worker(4661)] [INFO] Querying modifier status...
Oct 14 15:07:31 localhost espanso[4661]: 15:07:31 [worker(4661)] [INFO] inject module will use this keyboard layout: [R=, M=, L=us, V=, O=]
Oct 14 15:07:31 localhost espanso[4661]: 15:07:31 [worker(4661)] [INFO] using EVDEVInjector
Oct 14 15:07:31 localhost espanso[4661]: 15:07:31 [worker(4661)] [INFO] using WaylandFallbackClipboard
Oct 14 17:42:31 localhost espanso[4661]: 17:42:31 [worker(4661)] [WARN] detected outdated modifier records for Meta, releasing the state
Oct 14 17:46:36 localhost espanso[4653]: 17:46:36 [daemon(4653)] [INFO] configuration change detected, restarting worker process...
Oct 14 17:46:36 localhost espanso[4661]: 17:46:36 [worker(4661)] [INFO] engine eventloop has terminated, propagating exit event...
Oct 14 17:46:36 localhost espanso[4661]: 17:46:36 [worker(4661)] [INFO] waiting for engine exit mode...
Oct 14 17:46:36 localhost espanso[4661]: 17:46:36 [worker(4661)] [INFO] exiting worker process...
Oct 14 17:46:36 localhost espanso[4653]: 17:46:36 [daemon(4653)] [INFO] spawning the worker process...
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [INFO] reading configs from: "/var/home/talal/.config/espanso"
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [INFO] reading packages from: "/var/home/talal/.config/espanso/match/packages"
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [INFO] using runtime dir: "/var/home/talal/.cache/espanso"
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [INFO] system info: Fedora Linux v40 - kernel: 6.10.12-200.fc40.x86_64
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [INFO] using WaylandAppInfoProvider
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [INFO] binded to IPC unix socket: /var/home/talal/.cache/espanso/espansoworkerv2.sock
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [WARN] EVDEV backend is being used, but without enabling linux capabilities.
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [WARN]   Although you CAN run espanso EVDEV backend as root, it's not recommended due
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [WARN]   to security reasons. Espanso supports linux capabilities to limit the attack surface
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [INFO] monitoring the status of the daemon process
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [WARN]   area by only leveraging on the CAP_DAC_OVERRIDE capability (needed to work with
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [WARN]   /dev/input/* devices to detect and inject text) and disabling it as soon as the
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [WARN]   initial setup is completed.
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [INFO] detection module will use this keyboard layout: [R=, M=, L=us, V=, O=]
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [INFO] using EVDEVSource
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [INFO] Querying modifier status...
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [INFO] inject module will use this keyboard layout: [R=, M=, L=us, V=, O=]
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [INFO] using EVDEVInjector
Oct 14 17:46:36 localhost espanso[82919]: 17:46:36 [worker(82919)] [INFO] using WaylandFallbackClipboard
Oct 14 17:46:55 localhost espanso[4653]: 17:46:55 [daemon(4653)] [INFO] configuration change detected, restarting worker process...
Oct 14 17:46:55 localhost espanso[82919]: 17:46:55 [worker(82919)] [INFO] engine eventloop has terminated, propagating exit event...
Oct 14 17:46:55 localhost espanso[82919]: 17:46:55 [worker(82919)] [INFO] waiting for engine exit mode...
Oct 14 17:46:55 localhost espanso[82919]: 17:46:55 [worker(82919)] [INFO] exiting worker process...
Oct 14 17:46:55 localhost espanso[4653]: 17:46:55 [daemon(4653)] [INFO] spawning the worker process...
Oct 14 17:46:55 localhost espanso[101314]: 17:46:55 [worker(101314)] [INFO] reading configs from: "/var/home/talal/.config/espanso"
Oct 14 17:46:55 localhost espanso[101314]: 17:46:55 [worker(101314)] [INFO] reading packages from: "/var/home/talal/.config/espanso/match/packages"
Oct 14 17:46:55 localhost espanso[101314]: 17:46:55 [worker(101314)] [INFO] using runtime dir: "/var/home/talal/.cache/espanso"
Oct 14 17:46:55 localhost espanso[101314]: 17:46:55 [worker(101314)] [INFO] system info: Fedora Linux v40 - kernel: 6.10.12-200.fc40.x86_64
Oct 14 17:46:55 localhost espanso[101314]: 17:46:55 [worker(101314)] [INFO] using WaylandAppInfoProvider
Oct 14 17:46:55 localhost espanso[101314]: 17:46:55 [worker(101314)] [INFO] binded to IPC unix socket: /var/home/talal/.cache/espanso/espansoworkerv2.sock
Oct 14 17:46:55 localhost espanso[101314]: 17:46:55 [worker(101314)] [WARN] EVDEV backend is being used, but without enabling linux capabilities.
Oct 14 17:46:55 localhost espanso[101314]: 17:46:55 [worker(101314)] [WARN]   Although you CAN run espanso EVDEV backend as root, it's not recommended due
Oct 14 17:46:55 localhost espanso[101314]: 17:46:55 [worker(101314)] [WARN]   to security reasons. Espanso supports linux capabilities to limit the attack surface
Oct 14 17:46:55 localhost espanso[101314]: 17:46:55 [worker(101314)] [INFO] monitoring the status of the daemon process
Oct 14 17:46:55 localhost espanso[101314]: 17:46:55 [worker(101314)] [WARN]   area by only leveraging on the CAP_DAC_OVERRIDE capability (needed to work with
Oct 14 17:46:55 localhost espanso[101314]: 17:46:55 [worker(101314)] [WARN]   /dev/input/* devices to detect and inject text) and disabling it as soon as the
Oct 14 17:46:55 localhost espanso[101314]: 17:46:55 [worker(101314)] [WARN]   initial setup is completed.
Oct 14 17:46:55 localhost espanso[101314]: 17:46:55 [worker(101314)] [INFO] detection module will use this keyboard layout: [R=, M=, L=us, V=, O=]
Oct 14 17:46:55 localhost espanso[101314]: 17:46:55 [worker(101314)] [INFO] using EVDEVSource
Oct 14 17:46:56 localhost espanso[101314]: 17:46:56 [worker(101314)] [INFO] Querying modifier status...
Oct 14 17:46:56 localhost espanso[101314]: 17:46:56 [worker(101314)] [INFO] inject module will use this keyboard layout: [R=, M=, L=us, V=, O=]
Oct 14 17:46:56 localhost espanso[101314]: 17:46:56 [worker(101314)] [INFO] using EVDEVInjector
Oct 14 17:46:56 localhost espanso[101314]: 17:46:56 [worker(101314)] [INFO] using WaylandFallbackClipboard
Oct 14 17:56:00 localhost espanso[4653]: 17:56:00 [daemon(4653)] [INFO] configuration change detected, restarting worker process...
Oct 14 17:56:00 localhost espanso[101314]: 17:56:00 [worker(101314)] [INFO] engine eventloop has terminated, propagating exit event...
Oct 14 17:56:00 localhost espanso[101314]: 17:56:00 [worker(101314)] [INFO] waiting for engine exit mode...
Oct 14 17:56:00 localhost espanso[101314]: 17:56:00 [worker(101314)] [INFO] exiting worker process...
Oct 14 17:56:00 localhost espanso[4653]: 17:56:00 [daemon(4653)] [INFO] spawning the worker process...
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [INFO] reading configs from: "/var/home/talal/.config/espanso"
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [INFO] reading packages from: "/var/home/talal/.config/espanso/match/packages"
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [INFO] using runtime dir: "/var/home/talal/.cache/espanso"
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [INFO] system info: Fedora Linux v40 - kernel: 6.10.12-200.fc40.x86_64
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [INFO] binded to IPC unix socket: /var/home/talal/.cache/espanso/espansoworkerv2.sock
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [INFO] using WaylandAppInfoProvider
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [WARN] EVDEV backend is being used, but without enabling linux capabilities.
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [WARN]   Although you CAN run espanso EVDEV backend as root, it's not recommended due
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [INFO] monitoring the status of the daemon process
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [WARN]   to security reasons. Espanso supports linux capabilities to limit the attack surface
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [WARN]   area by only leveraging on the CAP_DAC_OVERRIDE capability (needed to work with
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [WARN]   /dev/input/* devices to detect and inject text) and disabling it as soon as the
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [WARN]   initial setup is completed.
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [INFO] detection module will use this keyboard layout: [R=, M=, L=us, V=, O=]
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [INFO] using EVDEVSource
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [INFO] Querying modifier status...
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [INFO] inject module will use this keyboard layout: [R=, M=, L=us, V=, O=]
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [INFO] using EVDEVInjector
Oct 14 17:56:00 localhost espanso[123331]: 17:56:00 [worker(123331)] [INFO] using WaylandFallbackClipboard
Oct 14 17:57:45 localhost espanso[123331]: 17:57:45 [worker(123331)] [WARN] detected outdated modifier records for Meta, releasing the state
Oct 14 18:01:05 localhost espanso[4653]: 18:01:05 [daemon(4653)] [INFO] configuration change detected, restarting worker process...
Oct 14 18:01:05 localhost espanso[123331]: 18:01:05 [worker(123331)] [INFO] engine eventloop has terminated, propagating exit event...
Oct 14 18:01:05 localhost espanso[123331]: 18:01:05 [worker(123331)] [INFO] waiting for engine exit mode...
Oct 14 18:01:05 localhost espanso[123331]: 18:01:05 [worker(123331)] [INFO] exiting worker process...
Oct 14 18:01:05 localhost espanso[4653]: 18:01:05 [daemon(4653)] [INFO] spawning the worker process...
Oct 14 18:01:05 localhost espanso[144898]: 18:01:05 [worker(144898)] [INFO] reading configs from: "/var/home/talal/.config/espanso"
Oct 14 18:01:05 localhost espanso[144898]: 18:01:05 [worker(144898)] [INFO] reading packages from: "/var/home/talal/.config/espanso/match/packages"
Oct 14 18:01:05 localhost espanso[144898]: 18:01:05 [worker(144898)] [INFO] using runtime dir: "/var/home/talal/.cache/espanso"
Oct 14 18:01:05 localhost espanso[144898]: 18:01:05 [worker(144898)] [INFO] system info: Fedora Linux v40 - kernel: 6.10.12-200.fc40.x86_64
Oct 14 18:01:05 localhost espanso[144898]: 18:01:05 [worker(144898)] [INFO] using WaylandAppInfoProvider
Oct 14 18:01:05 localhost espanso[144898]: 18:01:05 [worker(144898)] [INFO] binded to IPC unix socket: /var/home/talal/.cache/espanso/espansoworkerv2.sock
Oct 14 18:01:05 localhost espanso[144898]: 18:01:05 [worker(144898)] [WARN] EVDEV backend is being used, but without enabling linux capabilities.
Oct 14 18:01:05 localhost espanso[144898]: 18:01:05 [worker(144898)] [WARN]   Although you CAN run espanso EVDEV backend as root, it's not recommended due
Oct 14 18:01:05 localhost espanso[144898]: 18:01:05 [worker(144898)] [WARN]   to security reasons. Espanso supports linux capabilities to limit the attack surface
Oct 14 18:01:05 localhost espanso[144898]: 18:01:05 [worker(144898)] [INFO] monitoring the status of the daemon process
Oct 14 18:01:05 localhost espanso[144898]: 18:01:05 [worker(144898)] [WARN]   area by only leveraging on the CAP_DAC_OVERRIDE capability (needed to work with
Oct 14 18:01:05 localhost espanso[144898]: 18:01:05 [worker(144898)] [WARN]   /dev/input/* devices to detect and inject text) and disabling it as soon as the
Oct 14 18:01:05 localhost espanso[144898]: 18:01:05 [worker(144898)] [WARN]   initial setup is completed.
Oct 14 18:01:05 localhost espanso[144898]: 18:01:05 [worker(144898)] [INFO] detection module will use this keyboard layout: [R=, M=, L=us, V=, O=]
Oct 14 18:01:05 localhost espanso[144898]: 18:01:05 [worker(144898)] [INFO] using EVDEVSource
Oct 14 18:01:06 localhost espanso[144898]: 18:01:06 [worker(144898)] [INFO] Querying modifier status...
Oct 14 18:01:06 localhost espanso[144898]: 18:01:06 [worker(144898)] [INFO] inject module will use this keyboard layout: [R=, M=, L=us, V=, O=]
Oct 14 18:01:06 localhost espanso[144898]: 18:01:06 [worker(144898)] [INFO] using EVDEVInjector
Oct 14 18:01:06 localhost espanso[144898]: 18:01:06 [worker(144898)] [INFO] using WaylandFallbackClipboard
Oct 14 18:03:10 localhost espanso[144898]: 18:03:10 [worker(144898)] [WARN] detected outdated modifier records for Meta, releasing the state
Oct 14 18:07:30 localhost espanso[4653]: 18:07:30 [daemon(4653)] [INFO] configuration change detected, restarting worker process...
Oct 14 18:07:30 localhost espanso[144898]: 18:07:30 [worker(144898)] [INFO] engine eventloop has terminated, propagating exit event...
Oct 14 18:07:30 localhost espanso[144898]: 18:07:30 [worker(144898)] [INFO] waiting for engine exit mode...
Oct 14 18:07:30 localhost espanso[144898]: 18:07:30 [worker(144898)] [INFO] exiting worker process...
Oct 14 18:07:30 localhost espanso[4653]: 18:07:30 [daemon(4653)] [INFO] spawning the worker process...
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [INFO] reading configs from: "/var/home/talal/.config/espanso"
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [INFO] reading packages from: "/var/home/talal/.config/espanso/match/packages"
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [INFO] using runtime dir: "/var/home/talal/.cache/espanso"
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [INFO] system info: Fedora Linux v40 - kernel: 6.10.12-200.fc40.x86_64
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [INFO] binded to IPC unix socket: /var/home/talal/.cache/espanso/espansoworkerv2.sock
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [INFO] using WaylandAppInfoProvider
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [WARN] EVDEV backend is being used, but without enabling linux capabilities.
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [WARN]   Although you CAN run espanso EVDEV backend as root, it's not recommended due
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [WARN]   to security reasons. Espanso supports linux capabilities to limit the attack surface
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [WARN]   area by only leveraging on the CAP_DAC_OVERRIDE capability (needed to work with
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [INFO] monitoring the status of the daemon process
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [WARN]   /dev/input/* devices to detect and inject text) and disabling it as soon as the
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [WARN]   initial setup is completed.
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [INFO] detection module will use this keyboard layout: [R=, M=, L=us, V=, O=]
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [INFO] using EVDEVSource
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [INFO] Querying modifier status...
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [INFO] inject module will use this keyboard layout: [R=, M=, L=us, V=, O=]
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [INFO] using EVDEVInjector
Oct 14 18:07:30 localhost espanso[165573]: 18:07:30 [worker(165573)] [INFO] using WaylandFallbackClipboard
Oct 14 18:17:08 localhost espanso[4653]: 18:17:08 [daemon(4653)] [INFO] configuration change detected, restarting worker process...
Oct 14 18:17:08 localhost espanso[165573]: 18:17:08 [worker(165573)] [INFO] engine eventloop has terminated, propagating exit event...
Oct 14 18:17:08 localhost espanso[165573]: 18:17:08 [worker(165573)] [INFO] waiting for engine exit mode...
Oct 14 18:17:08 localhost espanso[165573]: 18:17:08 [worker(165573)] [INFO] exiting worker process...
Oct 14 18:17:08 localhost espanso[4653]: 18:17:08 [daemon(4653)] [INFO] spawning the worker process...
Oct 14 18:17:08 localhost espanso[189062]: 18:17:08 [worker(189062)] [INFO] reading configs from: "/var/home/talal/.config/espanso"
Oct 14 18:17:08 localhost espanso[189062]: 18:17:08 [worker(189062)] [INFO] reading packages from: "/var/home/talal/.config/espanso/match/packages"
Oct 14 18:17:08 localhost espanso[189062]: 18:17:08 [worker(189062)] [INFO] using runtime dir: "/var/home/talal/.cache/espanso"
Oct 14 18:17:08 localhost espanso[189062]: 18:17:08 [worker(189062)] [INFO] system info: Fedora Linux v40 - kernel: 6.10.12-200.fc40.x86_64
Oct 14 18:17:08 localhost espanso[189062]: 18:17:08 [worker(189062)] [INFO] using WaylandAppInfoProvider
Oct 14 18:17:08 localhost espanso[189062]: 18:17:08 [worker(189062)] [INFO] binded to IPC unix socket: /var/home/talal/.cache/espanso/espansoworkerv2.sock
Oct 14 18:17:08 localhost espanso[189062]: 18:17:08 [worker(189062)] [WARN] EVDEV backend is being used, but without enabling linux capabilities.
Oct 14 18:17:08 localhost espanso[189062]: 18:17:08 [worker(189062)] [WARN]   Although you CAN run espanso EVDEV backend as root, it's not recommended due
Oct 14 18:17:08 localhost espanso[189062]: 18:17:08 [worker(189062)] [WARN]   to security reasons. Espanso supports linux capabilities to limit the attack surface
Oct 14 18:17:08 localhost espanso[189062]: 18:17:08 [worker(189062)] [INFO] monitoring the status of the daemon process
Oct 14 18:17:08 localhost espanso[189062]: 18:17:08 [worker(189062)] [WARN]   area by only leveraging on the CAP_DAC_OVERRIDE capability (needed to work with
Oct 14 18:17:08 localhost espanso[189062]: 18:17:08 [worker(189062)] [WARN]   /dev/input/* devices to detect and inject text) and disabling it as soon as the
Oct 14 18:17:08 localhost espanso[189062]: 18:17:08 [worker(189062)] [WARN]   initial setup is completed.
Oct 14 18:17:08 localhost espanso[189062]: 18:17:08 [worker(189062)] [INFO] detection module will use this keyboard layout: [R=, M=, L=us, V=, O=]
Oct 14 18:17:08 localhost espanso[189062]: 18:17:08 [worker(189062)] [INFO] using EVDEVSource
Oct 14 18:17:09 localhost espanso[189062]: 18:17:09 [worker(189062)] [INFO] Querying modifier status...
Oct 14 18:17:09 localhost espanso[189062]: 18:17:09 [worker(189062)] [INFO] inject module will use this keyboard layout: [R=, M=, L=us, V=, O=]
Oct 14 18:17:09 localhost espanso[189062]: 18:17:09 [worker(189062)] [INFO] using EVDEVInjector
Oct 14 18:17:09 localhost espanso[189062]: 18:17:09 [worker(189062)] [INFO] using WaylandFallbackClipboard
Oct 14 18:22:46 localhost espanso[189062]: 18:22:46 [worker(189062)] [WARN] detected outdated modifier records for Meta, releasing the state
Oct 14 20:53:45 localhost espanso[189062]: 20:53:45 [worker(189062)] [WARN] detected outdated modifier records for Alt, releasing the state
Oct 16 03:32:12 localhost espanso[189062]: 03:32:12 [worker(189062)] [WARN] detected outdated modifier records for Alt, releasing the state
Oct 16 03:35:12 localhost espanso[189062]: 03:35:12 [worker(189062)] [WARN] detected outdated modifier records for Alt, releasing the state
Oct 16 05:39:57 localhost espanso[189062]: 05:39:57 [worker(189062)] [WARN] detected outdated modifier records for Meta, releasing the state
Oct 16 05:43:23 localhost espanso[189062]: 05:43:23 [worker(189062)] [WARN] detected outdated modifier records for Meta, releasing the state
My espanso service config
systemd.user.services.espanso = {
    Unit = {
        Description = "espanso";
    };
    Install = {
        WantedBy = ["default.target"];
    };
    Service = {
        ExecStart = "${pkgs.espanso-wayland}/bin/espanso launcher";
        Restart = "on-failure";
        RestartSec = 3;
        # Sandboxing
        LockPersonality = true;
        MemoryDenyWriteExecute = true;
        NoNewPrivileges = true;
        PrivateUsers = true;
        RestrictNamespaces = true;
        SystemCallArchitectures = "native";
        SystemCallFilter = "@system-service";
    };
};

@pitkling
Copy link
Contributor

Thanks @talal, that helped a lot!

Your espanso log indicates that the capabilities you granted via sudo setcap … to the espanso binary are not in effect (see the warning starting with the line [WARN] EVDEV backend is being used, but without enabling linux capabilities. in the user service's log). In that case, espanso needs some other ways to access /dev/input/* and /dev/uinput under Wayland. This is usually achieved by running it as root (when it is run as a system service) or by adding your user to a group that has access to those device files. Any chance your user account is part of a group like input, granting it access to /dev/input/* and /dev/uinput? Can you post the output of groups and ls -l /dev/uinput /dev/input/?

I tested this locally by adding myself to the input group (and temporarily changing the group/access rights of /dev/uinput, which is only readable by root on NixOS by default). After that, the espanso user service with your sandboxing options (and an unmodified espanso-wayland binary) worked fine.

Now, if I'm right then it might be difficult to add sandboxing to the service, at least in the case of espanso-wayland. Not only mine but also @n8henrie's NixOS PR #339594 does not work with your sandboxing options. I don't understand it enough to be sure, but the documentation of PrivateUsers (which seems to be required for basically any sandboxing ability in user services) indicates that when enabled, the user service has pretty much no capabilities. That would explain the behavior. Maybe one can reenable certain capabilities via CapabilityBoundingSet and/or AmbientCapabilities. I didn't yet have time to play around with that.

@talal
Copy link
Contributor Author

talal commented Oct 18, 2024

You're right, I forgot about the input group. I also use xremap which can be run without sudo by enabling the uinput module, adding the required udev rules, and adding user to the input group. Kindly see xremap's README for reference, you might get some hints from there.

$ groups
talal wheel input

$ lsmod | grep uinput
uinput                 20480  3

$ cat /etc/udev/rules.d/99-input.rules
KERNEL=="uinput", GROUP="input", TAG+="uaccess"

@pitkling
Copy link
Contributor

Ok, that explains why your espanso service had access to the input devices, thanks! 🙂

Unfortunately it seems sandboxing an espanso-wayland user service via Home Manager won't be possible without extra intervention on the system level (via the NixOS configuration or manual sudo-actions on other distributions). So I guess at best sandboxing could be an opt-in with hints in the documentation1 about how to enable corresponding access rights at least in NixOS? I guess on non-wayland system one could also think about activating sandboxing by default (although I haven't tested this). Any thoughts, @n8henrie?

Concerning the compatibility of this with the NixOS PRs #328890 and #339594: Any solution based on CAP_DAC_OVERRIDE (the "officially" suggested way to run Espanso as a non-privileged user on Wayland, used by both PRs) won't be compatible with a sandboxed user service. After some reading about systemd sandboxing and user namespaces it seems that:

Footnotes

  1. For NixOS systems, enabling sandboxing for an espanso user service would require something like
    config.hardware.uinput.enable = true;
    users.groups.input.members = [ "<username>" ];
    users.groups.uinput.members = [ "<username>" ];

@talal talal force-pushed the espanso-sandboxing branch from 040a06a to dfda5c3 Compare October 18, 2024 20:06
@talal talal force-pushed the espanso-sandboxing branch from dfda5c3 to 0678a95 Compare October 18, 2024 20:21
@talal
Copy link
Contributor Author

talal commented Oct 18, 2024

@rycee Since sandboxing for Espanso is tricky and requires further investigation. I've removed non-sandboxing changes from this PR and cherry-picked them into a separate PR (#5975) — this way they won't get blocked and can be merged independently.

@n8henrie @pitkling feel free to add to this PR or close it if sandboxing doesn't work out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants